using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx;
using HarmonyLib;
using Hearthstone;
using Hearthstone.Progression;
using PegasusLettuce;
using PegasusShared;
using PegasusUtil;
using UnityEngine;
using BepInEx.Configuration;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Mercenary
{
    public static class UtilsBattle
    {
		private static string encryptKey = "AsMx";
		static string Decrypt(string str)
		{
			DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();
			byte[] key = Encoding.Unicode.GetBytes(encryptKey);
			byte[] data = Convert.FromBase64String(str);
			MemoryStream MStream = new MemoryStream();
			CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);
			CStream.Write(data, 0, data.Length);
			CStream.FlushFinalBlock();
			return Encoding.Unicode.GetString(MStream.ToArray());
		}

		//对战
		public static int HandleBattle(int phaseID,
			bool enableTimeGear, int pveFightTime, int pvpFightTime)
        {
			if (enableTimeGear)
			{
				if (UtilsGui.modeConf.m_id == UiItemConst.模式_真人PVP.m_id)
				{
					HsMod.ConfigValue.Get().TimeGearValue = pvpFightTime;
				}
				else
				{
					HsMod.ConfigValue.Get().TimeGearValue = pveFightTime;
				}
			}

			if (phaseID == 3) return 0;

            UtilsLog.Log(string.Format("[状态] 对局进行中，phaseID={0},ResponseMode={1}",
                phaseID, GameState.Get().GetResponseMode()));
			if (phaseID == 0)
			{
				/*
				if (Main.deleteBreak.Value && Main.modeConf.Value == Mode.PVP)
				{
					Main.Sleep(10);
					return 0;
				}*/
				UtilsLog.Log("[对局中] 回合结束");
				InputManager.Get().DoEndTurnButton();
				return 0;
			}

			if (EndTurnButton.Get().m_ActorStateMgr.GetActiveStateType() == ActorStateType.ENDTURN_NO_MORE_PLAYS)
			{
				/*
				if (Main.deleteBreak.Value && Main.modeConf.Value == Mode.PVP)
				{
					Main.Sleep(10);
					return 0;
				}
				*/
				UtilsLog.Log("[对局中] 点击结束按钮");
				InputManager.Get().DoEndTurnButton();
				return 0;
			}

			// 策略计算
			List<BattleTarget> battleTargets = (
				StrategyUtils.GetStrategy(UtilsGui.strategyConf.m_name).GetBattleTargets(
				GameState.Get().GetTurn(),
				UtilsCom.BuildTargetFromCards(ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.OPPOSING).GetCards(), Player.Side.OPPOSING),
				UtilsCom.BuildTargetFromCards(ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.FRIENDLY).GetCards(), Player.Side.FRIENDLY),
				UtilsCom.BuildTargetFromCards(ZoneMgr.Get().FindZoneOfType<ZoneGraveyard>(Player.Side.OPPOSING).GetCards(), Player.Side.OPPOSING)));
			Dictionary<int, BattleTarget> dict = battleTargets.FindAll((BattleTarget i) => i.SkillId != -1).ToDictionary((BattleTarget i) => i.SkillId, (BattleTarget i) => i);
			foreach (BattleTarget battleTarget in battleTargets)
			{
				if (battleTarget.SkillId == -1)
					continue;
				if (!dict.ContainsKey(battleTarget.SkillId))
					dict.Add(battleTarget.SkillId, battleTarget);
			}

			// 选择目标阶段
			if (GameState.Get().GetResponseMode() == GameState.ResponseMode.OPTION_TARGET)
			{
				foreach (BattleTarget battleTarget in battleTargets)
					UtilsLog.Log(string.Format("[对局中] 策略判断 [SkillId:{0}] [TargetId:{1}] [TTYPE:{2}]",
							battleTarget.SkillId, battleTarget.TargetId, battleTarget.TargetType));

				List<Card> cards_opposite = ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.OPPOSING).GetCards().FindAll((Card i) => (i.GetActor().GetActorStateType() == ActorStateType.CARD_VALID_TARGET || i.GetActor().GetActorStateType() == ActorStateType.CARD_VALID_TARGET_MOUSE_OVER) && !i.GetEntity().IsStealthed());
				List<Card> cards_friend = ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.FRIENDLY).GetCards().FindAll((Card i) => (i.GetActor().GetActorStateType() == ActorStateType.CARD_VALID_TARGET || i.GetActor().GetActorStateType() == ActorStateType.CARD_VALID_TARGET_MOUSE_OVER));
				string strlog = "";
				foreach (Card card1 in cards_opposite)
					strlog += string.Format("{0}({1},{2})\t",
						card1.GetEntity().GetEntityId(), card1.GetEntity().GetCurrentHealth(), card1.GetEntity().GetDefHealth());
				UtilsLog.Log(string.Format("[对局中] 场面：敌方 {0}", strlog));
				strlog = "";
				foreach (Card card1 in cards_friend)
					strlog += string.Format("{0}({1},{2})\t",
						card1.GetEntity().GetEntityId(), card1.GetEntity().GetCurrentHealth(), card1.GetEntity().GetDefHealth());
				UtilsLog.Log(string.Format("[对局中] 场面：友方 {0}", strlog));


				//这个是当前停留的技能id
				Network.Options.Option.SubOption networkSubOption = GameState.Get().GetSelectedNetworkSubOption();
				UtilsLog.Log(string.Format("[对局中] 技能目标 当前技能 [SID:{0}]",
					networkSubOption.ID));

				Card card = null;
				// 先
				if (dict.ContainsKey(networkSubOption.ID) && dict[networkSubOption.ID].TargetId != -1)
				{
					UtilsLog.LogStra("[对局中] 技能目标 匹配策略");
					if (dict[networkSubOption.ID].TargetType == TARGETTYPE.UNSPECIFIED)
					{
						card = cards_opposite.Find((Card i) => i.GetEntity().GetEntityId() == dict[networkSubOption.ID].TargetId);
						if (card == null)
							card = cards_friend.Find((Card i) => i.GetEntity().GetEntityId() == dict[networkSubOption.ID].TargetId);
					}
					else if (dict[networkSubOption.ID].TargetType == TARGETTYPE.FRIENDLY)
					{
						card = cards_friend.Find((Card i) => i.GetEntity().GetEntityId() == dict[networkSubOption.ID].TargetId);
					}
				}

				if (card == null && cards_opposite.Count != 0)
				{
					card = cards_opposite[0];
					UtilsLog.LogStra("[对局中] 技能目标 敌方1号位");
				}
				if (card == null && cards_friend.Count != 0)
				{
					UtilsLog.LogStra("[对局中] 技能目标 友方首位");
					card = cards_friend[0];
				}
				if (card == null)
				{
					UtilsLog.LogStra("[对局中] 技能目标 无可用目标 过");
					InputManager.Get().DoEndTurnButton();
				}
				Traverse.Create(InputManager.Get()).Method("DoNetworkOptionTarget", new object[]
				{
					card.GetEntity()
				}).GetValue();
			}
			else if (GameState.Get().GetResponseMode() == GameState.ResponseMode.OPTION)
			{
				//特殊处理
				if (UtilsGui.autoConcede && UtilsGui.modeConf.m_id == UiItemConst.模式_真人PVP.m_id)
				{
					GameState.Get().Concede();
					UtilsLog.LogStra("[配置] Pvp自动投降");
					return 0;
				}
				if (UtilsGui.modeConf.m_id == UiItemConst.模式_真人PVP.m_id &&
					GameState.Get().GetTurn() >= 3)
				{
					string name = HsMod.ConfigValue.Get().CacheOpponentFullName;
					try 
					{
						if (!string.IsNullOrEmpty(name) &&
							(name.Contains(Decrypt("HHHKtq93H/M=")) ||
							name.Contains(Decrypt("IsW14IjwV1QGYmXMiiyjOi7Qbuw14ZWx"))))
						{
							GameState.Get().Concede();
							UtilsLog.LogStra("[配置] 遇到君莫笑，Pvp自动投降");
							return 0;
						}
					}
					catch (Exception e)
					{
						UtilsLog.LogStra(e.ToString());
					}
				}
				if (UtilsGui.modeConf.m_id == UiItemConst.模式_挂机收菜.m_id)
				{
					if (UtilsGui.readyToHang)
					{
						int time = UtilsGui.pveInterval;
						if (UtilsLog.WriteAwakeTime(time))
						{
							UtilsLog.Log(string.Format(
								"[战斗中] 初次进入战斗，休息{0}分{1}秒后再见~", time / 60, time % 60));
							Application.Quit();
						}
						else
						{
							UtilsLog.Log(string.Format("[战斗中] 收菜时间写入失败，稍后再试~"));
							return 0;
						}
					}
					if (!UtilsGui.needToHang)
					{
						GameState.Get().Concede();
						UtilsLog.LogStra("[收菜] 收菜时间截至，自动投降");
						return 0;
					}
				}

				//上怪
				if (phaseID == 1 && EndTurnButton.Get().m_ActorStateMgr.GetActiveStateType() == ActorStateType.ENDTURN_YOUR_TURN)
				{
					if (GameMgr.Get().GetGameType() == GameType.GT_MERCENARIES_PVE && UtilsGui.pvpDelayTime < 30)
						InputManager.Get().DoEndTurnButton();
					ZonePlay zonePlay = ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.FRIENDLY);
					ZoneHand zoneHand = ZoneMgr.Get().FindZoneOfType<ZoneHand>(Player.Side.FRIENDLY);
					if (zoneHand != null)
					{
						(int hand_index, int play_index) = StrategyUtils.GetStrategy(UtilsGui.strategyConf.m_name).GetEnterOrder(
							UtilsCom.BuildTargetFromCards(zoneHand.GetCards(), Player.Side.FRIENDLY),
							UtilsCom.BuildTargetFromCards(zonePlay.GetCards(), Player.Side.FRIENDLY)
							);

						GameState gameState = GameState.Get();
						if (gameState != null)
						{
							UtilsLog.LogStra(string.Format("[佣兵登场] 选择[佣兵{0}:{1}]，位置[{2}]",
								hand_index, zoneHand.GetCardAtIndex(hand_index).GetEntity().GetName(), play_index));
							gameState.SetSelectedOption(hand_index + 1);
							gameState.SetSelectedSubOption(-1);
							gameState.SetSelectedOptionTarget(0);
							gameState.SetSelectedOptionPosition(play_index + 1);
							gameState.SendOption();

							Main.Sleep(UtilsGui.pvpDelayTime);
							UtilsLog.LogStra(string.Format("[佣兵上场等待] 剩余时间:{0}秒", UtilsGui.pvpDelayTime));

						}
						return 0;
					}
				}
				// 佣兵技能选择
				if (phaseID == 2)
				{
					ZonePlay zonePlay_opposing = ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.OPPOSING);
					ZonePlay zonePlay_friendly = ZoneMgr.Get().FindZoneOfType<ZonePlay>(Player.Side.FRIENDLY);
					if (UtilsGui.modeConf.m_id == UiItemConst.模式_真人PVP.m_id)
					{
						UtilsInfo.MercRecord(zonePlay_opposing);
					}
					if (null == zonePlay_opposing.GetCards().Find((Card i) => false == i.GetEntity().IsStealthed()))
					{
						UtilsLog.LogStra("[对局中] 他们都藏起来了？？！！");
						InputManager.Get().DoEndTurnButton();
						return 0;
					}
					Entity currentSelectMerc_Entity = ZoneMgr.Get().GetLettuceAbilitiesSourceEntity();
					if (currentSelectMerc_Entity == null)
					{
						foreach (Card card in zonePlay_friendly.GetCards())
						{
							Entity entity = card.GetEntity();
							if (!entity.HasSelectedLettuceAbility() || !entity.HasTag(GAME_TAG.LETTUCE_HAS_MANUALLY_SELECTED_ABILITY))
							{
								UtilsLog.LogStra(string.Format("[对局中] 佣兵选择 [{0}]的技能界面", entity.GetName()));
								ZoneMgr.Get().DisplayLettuceAbilitiesForEntity(entity);
								return 1;
							}
						}
					}
					else
					{
						BattleTarget currentMerc_BattleTarget = battleTargets.Find((BattleTarget i) => i.MercName == currentSelectMerc_Entity.GetName());
						// 策略规定此佣兵可以操作
						if (currentMerc_BattleTarget == null || currentMerc_BattleTarget.NeedActive == true)
						{
							UtilsLog.LogStra(string.Format("[对局中] 技能选择 操作佣兵 [{0}]", currentSelectMerc_Entity.GetName()));
							Card card = null;
							List<Card> displayedLettuceAbilityCards = ZoneMgr.Get().GetLettuceZoneController().GetDisplayedLettuceAbilityCards();
							foreach (BattleTarget batterTarget in battleTargets)
							{
								card = displayedLettuceAbilityCards.Find((Card i) => i.GetEntity().GetEntityId() == batterTarget.SkillId && GameState.Get().HasResponse(i.GetEntity(), new bool?(false)));
								if (card != null)
									break;
							}
							if (card != null)
							{
								UtilsLog.LogStra(string.Format("[对局中] 技能选择 匹配策略[{0}]", card.GetEntity().GetName()));
							}
							else
							{
								card = displayedLettuceAbilityCards.Find((Card i) => GameState.Get().HasResponse(i.GetEntity(), new bool?(false)));
								UtilsLog.LogStra(string.Format("[对局中] 技能选择 顺序选择[{0}]", card.GetEntity().GetName()));
							}
							Traverse.Create(InputManager.Get()).Method("HandleClickOnCardInBattlefield", new object[]
							{
							card.GetEntity(),
							true
							}).GetValue();
							return 1;
						}
						// 策略规定此佣兵不可以操作
						else
						{
							UtilsLog.LogStra(string.Format("[对局中] 操作佣兵 设置为不操作[{0}]", currentSelectMerc_Entity.GetName()));
							Dictionary<string, bool> dict_mercactive = new Dictionary<string, bool>();
							foreach (BattleTarget battleTarget in battleTargets)
							{
								if (battleTarget.MercName.Length <= 0)
									continue;
								if (!dict_mercactive.ContainsKey(battleTarget.MercName))
									dict_mercactive.Add(battleTarget.MercName, battleTarget.NeedActive);
							}
							bool result = false;
							Card nextSelectMerc_Card = zonePlay_friendly.GetCards().Find(
								(Card i) =>
								(!i.GetEntity().HasSelectedLettuceAbility() || !i.GetEntity().HasTag(GAME_TAG.LETTUCE_HAS_MANUALLY_SELECTED_ABILITY)) &&
								(false == dict_mercactive.TryGetValue(i.GetEntity().GetName(), out result) || result == true)
								);
							if (nextSelectMerc_Card != null)
							{
								UtilsLog.LogStra(string.Format("[对局中] 操作佣兵 手动选择下一个佣兵[{0}]", nextSelectMerc_Card.GetEntity().GetName()));
								ZoneMgr.Get().DisplayLettuceAbilitiesForEntity(nextSelectMerc_Card.GetEntity());
								return 1;
							}
							else
							{
								UtilsLog.LogStra(string.Format("[对局中] 操作佣兵 无可操作佣兵 结束回合"));
								InputManager.Get().DoEndTurnButton();
								return 1;
							}
						}
					}
				}
			}
			// 抉择
			else if (GameState.Get().GetResponseMode() == GameState.ResponseMode.SUB_OPTION)
			{
				List<Card> friendlyCards = ChoiceCardMgr.Get().GetFriendlyCards();
				int skill_id = ChoiceCardMgr.Get().GetSubOptionParentCard().GetEntity().GetEntityId();
				int subskill_index = friendlyCards.Count - 1;
				if (dict.ContainsKey(skill_id) && dict[skill_id].SubSkillIndex != -1)
				{
					subskill_index = dict[skill_id].SubSkillIndex;
				}
				UtilsLog.LogStra("[对局中] 技能选择 使用抉择技能index： " + subskill_index.ToString());
				InputManager.Get().HandleClickOnSubOption(friendlyCards[subskill_index].GetEntity(), false);
				return 1;
			}
			return 0;
        }
    }
}